package com.atguigu.syt.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.syt.hosp.repository.ScheduleRepository;
import com.atguigu.syt.hosp.service.ScheduleService;
import com.atguigu.syt.hosp.utils.DateUtil;
import com.atguigu.syt.model.hosp.Schedule;
import com.atguigu.syt.vo.hosp.ScheduleRuleVo;
import org.joda.time.DateTime;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ScheduleServiceImpl implements ScheduleService {
    @Resource
    private ScheduleRepository scheduleRepository;
    @Resource
    private MongoTemplate mongoTemplate;
    /**
     * 保存排班信息
     * @param map
     */
    @Override
    public void save(Map<String, Object> map) {
        Schedule sch =
                JSONObject.parseObject(JSONObject.toJSONString(map), Schedule.class);
        Schedule schedule = scheduleRepository.
                findByHoscodeAndHosScheduleId(sch.getHoscode(), sch.getHosScheduleId());
        if (schedule != null){
            sch.setId(schedule.getId());
            scheduleRepository.save(sch);
        } else {
            scheduleRepository.save(sch);
        }
    }

    @Override
    public Page<Schedule> selectPage(int page, int limit, String hoscode) {

        Pageable pageable = PageRequest.of(page - 1, limit, Sort.by(Sort.Direction.ASC, "workDate"));

        Schedule schedule = new Schedule();
        schedule.setHoscode(hoscode);
        Example<Schedule> example = Example.of(schedule);
        Page<Schedule> pages = scheduleRepository.findAll(example, pageable);
        return pages;
    }

    @Override
    public void remove(String hoscode, String hosScheduleId) {
        Schedule Schedule = scheduleRepository.findByHoscodeAndHosScheduleId(hoscode, hosScheduleId);
        if (Schedule != null ){
            scheduleRepository.deleteById(Schedule.getId());
        }
    }

    /**
     * 根据医院编号 和 科室编号 ，查询排班规则（按日期展示）
     * @param page
     * @param limit
     * @param hoscode
     * @param depcode
     * @return
     */
    @Override
    public Map<String, Object> getScheduleRule(Long page, Long limit, String hoscode, String depcode) {
        //获取查询结果
        //List<Schedule> list = mongoTemplate.findAll(Schedule.class);
        //查询条件：根据医院编号和科室编号查询
        Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode);
        //根据工作日workDate期进行分组
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation
                //2 按照日期分组 select workDate as workDate from schedule group by workDate
                .group("workDate").first("workDate").as("workDate")
                //3 可预约数
                .sum("reservedNumber").as("reservedNumber")
                //4 剩余预约数
                .sum("availableNumber").as("availableNumber"),
                //5 排序
                Aggregation.sort(Sort.Direction.ASC,"workDate"),
                //6 分页
                Aggregation.skip((page-1)*limit),
                Aggregation.limit(limit)
        );
        //执行查询，查询Schedule集合，将文档中的同名字段数据存入BookingScheduleRuleVo类
        AggregationResults<ScheduleRuleVo> aggResults =
                mongoTemplate.aggregate(agg, Schedule.class, ScheduleRuleVo.class);
        //获取查询结果
        List<ScheduleRuleVo> list = aggResults.getMappedResults();


        //分组查询后的总记录数
        Aggregation totalAgg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("workDate")
        );
        AggregationResults<ScheduleRuleVo> totalAggResults = mongoTemplate.aggregate(totalAgg, Schedule.class, ScheduleRuleVo.class);
        int total = totalAggResults.getMappedResults().size();
        //根据日期计算对应星期获取 （iter）
        for (ScheduleRuleVo scheduleRuleVo : list) {
            Date workDate = scheduleRuleVo.getWorkDate();
            String dayOfWeek = DateUtil.getDayOfWeek(new DateTime(workDate));
            scheduleRuleVo.setDayOfWeek(dayOfWeek);
        }
        //设置最终数据，进行返回
        Map<String, Object> result = new HashMap<>();
        result.put("list",list);
        result.put("total",total);
        return result;
    }

    /**
     * 据医院编号 、科室编号和工作日期，查询排班详细信息
     * @param hoscode
     * @param depcode
     * @param workDate
     * @return
     */
    @Override
    public List<Schedule> getScheduleList(String hoscode, String depcode, String workDate) {
        List<Schedule> list= scheduleRepository.findByHoscodeAndDepcodeAndWorkDate(hoscode,
                depcode, new DateTime(workDate).toDate());
        return list;
    }
}
